package com.evan.review.ipc;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Process;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.evan.review.R;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 广播通信示例
 * 演示如何使用广播机制进行进程间通信
 */
public class BroadcastDemoActivity extends AppCompatActivity {

    // 广播Action常量
    private static final String ACTION_NORMAL_BROADCAST = "com.evan.review.action.NORMAL_BROADCAST";
    private static final String ACTION_ORDERED_BROADCAST = "com.evan.review.action.ORDERED_BROADCAST";
    private static final String ACTION_LOCAL_BROADCAST = "com.evan.review.action.LOCAL_BROADCAST";
    private static final String ACTION_STICKY_BROADCAST = "com.evan.review.action.STICKY_BROADCAST";

    // 广播数据键
    private static final String EXTRA_MESSAGE = "message";
    private static final String EXTRA_TIMESTAMP = "timestamp";
    private static final String EXTRA_SENDER_PID = "sender_pid";

    private TextView tvReceivedMessages;
    private EditText etMessage;
    private Button btnSendNormal;
    private Button btnSendOrdered;
    private Button btnSendLocal;
    private Button btnSendSticky;
    private Button btnLaunchRemote;
    private Button btnShowInfo;

    // 广播接收器
    private BroadcastReceiver normalReceiver;
    private BroadcastReceiver orderedReceiver;
    private BroadcastReceiver localReceiver;
    private BroadcastReceiver stickyReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcast_demo);

        // 初始化视图
        initViews();
        // 设置点击监听
        setupListeners();
        // 注册广播接收器
        registerReceivers();

        // 显示当前进程ID
        appendMessage("当前进程ID: " + Process.myPid());
    }

    private void initViews() {
        tvReceivedMessages = findViewById(R.id.tv_received_messages);
        etMessage = findViewById(R.id.et_broadcast_message);
        btnSendNormal = findViewById(R.id.btn_send_normal);
        btnSendOrdered = findViewById(R.id.btn_send_ordered);
        btnSendLocal = findViewById(R.id.btn_send_local);
        btnSendSticky = findViewById(R.id.btn_send_sticky);
        btnLaunchRemote = findViewById(R.id.btn_launch_remote_process);
        btnShowInfo = findViewById(R.id.btn_broadcast_info);
    }

    private void setupListeners() {
        // 发送普通广播
        btnSendNormal.setOnClickListener(v -> sendNormalBroadcast());

        // 发送有序广播
        btnSendOrdered.setOnClickListener(v -> sendOrderedBroadcast());

        // 发送本地广播
        btnSendLocal.setOnClickListener(v -> sendLocalBroadcast());

        // 发送粘性广播
        btnSendSticky.setOnClickListener(v -> sendStickyBroadcast());

        // 启动远程进程
        btnLaunchRemote.setOnClickListener(v -> launchRemoteProcess());

        // 显示广播介绍
        btnShowInfo.setOnClickListener(v -> showBroadcastInfo());
    }

    /**
     * 注册各种广播接收器
     */
    private void registerReceivers() {
        // 普通广播接收器
        normalReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                processReceivedBroadcast(intent, "普通广播");
            }
        };
        registerReceiver(normalReceiver, new IntentFilter(ACTION_NORMAL_BROADCAST));

        // 有序广播接收器
        orderedReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                processReceivedBroadcast(intent, "有序广播");
                
                // 可以修改结果数据供后续接收器使用
                setResultData("已被修改的结果");
                
                // 可以中止广播传递
                // abortBroadcast();
            }
        };
        registerReceiver(orderedReceiver, new IntentFilter(ACTION_ORDERED_BROADCAST));

        // 本地广播接收器
        localReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                processReceivedBroadcast(intent, "本地广播");
            }
        };
        LocalBroadcastManager.getInstance(this)
                .registerReceiver(localReceiver, new IntentFilter(ACTION_LOCAL_BROADCAST));

        // 粘性广播接收器
        stickyReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                processReceivedBroadcast(intent, "粘性广播");
            }
        };
        registerReceiver(stickyReceiver, new IntentFilter(ACTION_STICKY_BROADCAST));
    }

    /**
     * 处理接收到的广播
     */
    private void processReceivedBroadcast(Intent intent, String type) {
        if (intent != null) {
            String message = intent.getStringExtra(EXTRA_MESSAGE);
            long timestamp = intent.getLongExtra(EXTRA_TIMESTAMP, 0);
            int senderPid = intent.getIntExtra(EXTRA_SENDER_PID, 0);
            
            String timeString = new SimpleDateFormat("HH:mm:ss", Locale.getDefault())
                    .format(new Date(timestamp));
            
            String receivedMessage = String.format("收到%s：\n消息：%s\n发送者PID：%s\n时间：%s",
                    type, message, senderPid, timeString);
            
            appendMessage(receivedMessage);
        }
    }

    /**
     * 发送普通广播
     */
    private void sendNormalBroadcast() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        Intent intent = new Intent(ACTION_NORMAL_BROADCAST);
        intent.putExtra(EXTRA_MESSAGE, message);
        intent.putExtra(EXTRA_TIMESTAMP, System.currentTimeMillis());
        intent.putExtra(EXTRA_SENDER_PID, Process.myPid());
        
        sendBroadcast(intent);
        Toast.makeText(this, "已发送普通广播", Toast.LENGTH_SHORT).show();
    }

    /**
     * 发送有序广播
     */
    private void sendOrderedBroadcast() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        Intent intent = new Intent(ACTION_ORDERED_BROADCAST);
        intent.putExtra(EXTRA_MESSAGE, message);
        intent.putExtra(EXTRA_TIMESTAMP, System.currentTimeMillis());
        intent.putExtra(EXTRA_SENDER_PID, Process.myPid());
        
        // 发送有序广播，可以指定初始数据、权限、接收器等参数
        sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 最终接收器，可以获取到经过所有接收器处理后的结果
                String finalResult = getResultData();
                appendMessage("有序广播最终结果: " + finalResult);
            }
        }, null, 0, null, null);
        
        Toast.makeText(this, "已发送有序广播", Toast.LENGTH_SHORT).show();
    }

    /**
     * 发送本地广播
     */
    private void sendLocalBroadcast() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        Intent intent = new Intent(ACTION_LOCAL_BROADCAST);
        intent.putExtra(EXTRA_MESSAGE, message);
        intent.putExtra(EXTRA_TIMESTAMP, System.currentTimeMillis());
        intent.putExtra(EXTRA_SENDER_PID, Process.myPid());
        
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        Toast.makeText(this, "已发送本地广播", Toast.LENGTH_SHORT).show();
    }

    /**
     * 发送粘性广播
     * 注意：Android 8.0后，系统不再支持粘性广播，这里仅作演示
     */
    private void sendStickyBroadcast() {
        String message = getMessageText();
        if (message.isEmpty()) return;
        
        Intent intent = new Intent(ACTION_STICKY_BROADCAST);
        intent.putExtra(EXTRA_MESSAGE, message);
        intent.putExtra(EXTRA_TIMESTAMP, System.currentTimeMillis());
        intent.putExtra(EXTRA_SENDER_PID, Process.myPid());
        
        try {
            // 发送粘性广播需要特殊权限
            sendStickyBroadcast(intent);
            Toast.makeText(this, "已发送粘性广播", Toast.LENGTH_SHORT).show();
        } catch (SecurityException e) {
            Toast.makeText(this, "发送粘性广播失败: 需要BROADCAST_STICKY权限", 
                    Toast.LENGTH_SHORT).show();
            appendMessage("发送粘性广播失败: " + e.getMessage());
        }
    }

    /**
     * 启动远程进程
     */
    private void launchRemoteProcess() {
        Intent intent = new Intent(this, RemoteProcessActivity.class);
        intent.putExtra("from_broadcast_demo", true);
        startActivity(intent);
    }

    /**
     * 显示广播介绍对话框
     */
    private void showBroadcastInfo() {
        new androidx.appcompat.app.AlertDialog.Builder(this)
                .setTitle("广播通信介绍")
                .setMessage("广播是Android中的一种消息传递机制，可用于组件间和进程间通信。\n\n" +
                        "广播类型：\n" +
                        "1. 普通广播：同时发送给所有接收器，无序\n" +
                        "2. 有序广播：按优先级顺序发送，可拦截修改\n" +
                        "3. 本地广播：仅在应用内传递，高效安全\n" +
                        "4. 粘性广播：新注册的接收器可收到之前的广播(已废弃)\n\n" +
                        "适用场景：\n" +
                        "- 系统事件通知（电量变化、网络状态等）\n" +
                        "- 应用内/应用间事件通知\n" +
                        "- 发布/订阅模式的实现\n\n" +
                        "注意事项：\n" +
                        "- Android 8.0+对隐式广播有限制\n" +
                        "- 广播接收器生命周期短，不适合执行耗时操作\n" +
                        "- 应用内通信优先使用LocalBroadcastManager")
                .setPositiveButton("了解", null)
                .show();
    }

    /**
     * 获取输入的消息文本
     */
    private String getMessageText() {
        String message = etMessage.getText().toString().trim();
        if (message.isEmpty()) {
            message = "测试广播消息 " + System.currentTimeMillis();
        }
        return message;
    }

    /**
     * 添加消息到显示区域
     */
    private void appendMessage(String message) {
        String currentText = tvReceivedMessages.getText().toString();
        tvReceivedMessages.setText(currentText + "\n\n" + message);
    }

    @Override
    protected void onDestroy() {
        // 注销广播接收器
        unregisterReceiver(normalReceiver);
        unregisterReceiver(orderedReceiver);
        LocalBroadcastManager.getInstance(this).unregisterReceiver(localReceiver);
        unregisterReceiver(stickyReceiver);
        
        super.onDestroy();
    }
} 